package main

import (
	"context"
	"fmt"
	"log"
	"math"
	"strconv"
	"strings"
	"time"

	"demo2/mcpserver/mcp"
)

// TimeService 提供时间相关的服务
type TimeService struct{}

// GetTimeByLocation 根据位置获取时间
func (ts *TimeService) GetTimeByLocation(location string) (string, error) {
	log.Printf("[MCP-TIME] 🕐 收到时间查询请求，地点: %s", location)
	
	// 简化的时区映射
	timezones := map[string]string{
		"北京":   "Asia/Shanghai",
		"上海":   "Asia/Shanghai",
		"东京":   "Asia/Tokyo",
		"纽约":   "America/New_York",
		"伦敦":   "Europe/London",
		"巴黎":   "Europe/Paris",
		"洛杉矶":  "America/Los_Angeles",
		"悉尼":   "Australia/Sydney",
		"新加坡":  "Asia/Singapore",
		"香港":   "Asia/Hong_Kong",
		"台北":   "Asia/Taipei",
		"首尔":   "Asia/Seoul",
		"莫斯科":  "Europe/Moscow",
		"迪拜":   "Asia/Dubai",
		"孟买":   "Asia/Kolkata",
		"曼谷":   "Asia/Bangkok",
		"雅加达":  "Asia/Jakarta",
		"马尼拉":  "Asia/Manila",
		"吉隆坡":  "Asia/Kuala_Lumpur",
		"河内":   "Asia/Ho_Chi_Minh",
		"beijing": "Asia/Shanghai",
		"shanghai": "Asia/Shanghai",
		"tokyo": "Asia/Tokyo",
		"newyork": "America/New_York",
		"london": "Europe/London",
		"paris": "Europe/Paris",
		"losangeles": "America/Los_Angeles",
		"sydney": "Australia/Sydney",
		"singapore": "Asia/Singapore",
		"hongkong": "Asia/Hong_Kong",
		"taipei": "Asia/Taipei",
		"seoul": "Asia/Seoul",
		"moscow": "Europe/Moscow",
		"dubai": "Asia/Dubai",
		"mumbai": "Asia/Kolkata",
		"bangkok": "Asia/Bangkok",
		"jakarta": "Asia/Jakarta",
		"manila": "Asia/Manila",
		"kualalumpur": "Asia/Kuala_Lumpur",
		"hanoi": "Asia/Ho_Chi_Minh",
	}

	// 清理输入并查找时区
	cleanLocation := strings.ToLower(strings.ReplaceAll(location, " ", ""))
	log.Printf("[MCP-TIME] 🔍 清理后的地点: %s", cleanLocation)
	
	timezone, exists := timezones[cleanLocation]
	if !exists {
		log.Printf("[MCP-TIME] ❌ 不支持的地点: %s", location)
		return "", fmt.Errorf("不支持的位置: %s", location)
	}
	
	log.Printf("[MCP-TIME] 📍 找到时区: %s -> %s", location, timezone)

	// 加载时区
	loc, err := time.LoadLocation(timezone)
	if err != nil {
		log.Printf("[MCP-TIME] ❌ 加载时区失败: %v", err)
		return "", fmt.Errorf("加载时区失败: %v", err)
	}

	// 获取当前时间
	now := time.Now().In(loc)
	result := fmt.Sprintf("%s的当前时间是: %s", location, now.Format("2006-01-02 15:04:05 MST"))
	
	log.Printf("[MCP-TIME] ✅ 时间查询成功: %s", result)
	return result, nil
}

// CalculatorService 提供计算服务
type CalculatorService struct{}

// Calculate 执行基本的数学计算
func (cs *CalculatorService) Calculate(expression string) (string, error) {
	log.Printf("[MCP-CALC] 🧮 收到计算请求，表达式: %s", expression)
	
	// 简单的表达式解析器
	expression = strings.ReplaceAll(expression, " ", "")
	log.Printf("[MCP-CALC] 🔧 清理后的表达式: %s", expression)
	
	// 支持基本的四则运算
	if strings.Contains(expression, "+") {
		log.Printf("[MCP-CALC] ➕ 检测到加法运算")
		parts := strings.Split(expression, "+")
		if len(parts) != 2 {
			log.Printf("[MCP-CALC] ❌ 无效的加法表达式，部分数量: %d", len(parts))
			return "", fmt.Errorf("无效的加法表达式")
		}
		a, err1 := strconv.ParseFloat(parts[0], 64)
		b, err2 := strconv.ParseFloat(parts[1], 64)
		if err1 != nil || err2 != nil {
			log.Printf("[MCP-CALC] ❌ 数字解析失败: %v, %v", err1, err2)
			return "", fmt.Errorf("无效的数字")
		}
		result := fmt.Sprintf("%.2f", a+b)
		log.Printf("[MCP-CALC] ✅ 加法计算完成: %f + %f = %s", a, b, result)
		return result, nil
	}
	
	if strings.Contains(expression, "-") {
		log.Printf("[MCP-CALC] ➖ 检测到减法运算")
		parts := strings.Split(expression, "-")
		if len(parts) != 2 {
			log.Printf("[MCP-CALC] ❌ 无效的减法表达式，部分数量: %d", len(parts))
			return "", fmt.Errorf("无效的减法表达式")
		}
		a, err1 := strconv.ParseFloat(parts[0], 64)
		b, err2 := strconv.ParseFloat(parts[1], 64)
		if err1 != nil || err2 != nil {
			log.Printf("[MCP-CALC] ❌ 数字解析失败: %v, %v", err1, err2)
			return "", fmt.Errorf("无效的数字")
		}
		result := fmt.Sprintf("%.2f", a-b)
		log.Printf("[MCP-CALC] ✅ 减法计算完成: %f - %f = %s", a, b, result)
		return result, nil
	}
	
	if strings.Contains(expression, "*") {
		log.Printf("[MCP-CALC] ✖️ 检测到乘法运算")
		parts := strings.Split(expression, "*")
		if len(parts) != 2 {
			log.Printf("[MCP-CALC] ❌ 无效的乘法表达式，部分数量: %d", len(parts))
			return "", fmt.Errorf("无效的乘法表达式")
		}
		a, err1 := strconv.ParseFloat(parts[0], 64)
		b, err2 := strconv.ParseFloat(parts[1], 64)
		if err1 != nil || err2 != nil {
			log.Printf("[MCP-CALC] ❌ 数字解析失败: %v, %v", err1, err2)
			return "", fmt.Errorf("无效的数字")
		}
		result := fmt.Sprintf("%.2f", a*b)
		log.Printf("[MCP-CALC] ✅ 乘法计算完成: %f * %f = %s", a, b, result)
		return result, nil
	}
	
	if strings.Contains(expression, "/") {
		log.Printf("[MCP-CALC] ➗ 检测到除法运算")
		parts := strings.Split(expression, "/")
		if len(parts) != 2 {
			log.Printf("[MCP-CALC] ❌ 无效的除法表达式，部分数量: %d", len(parts))
			return "", fmt.Errorf("无效的除法表达式")
		}
		a, err1 := strconv.ParseFloat(parts[0], 64)
		b, err2 := strconv.ParseFloat(parts[1], 64)
		if err1 != nil || err2 != nil {
			log.Printf("[MCP-CALC] ❌ 数字解析失败: %v, %v", err1, err2)
			return "", fmt.Errorf("无效的数字")
		}
		if b == 0 {
			log.Printf("[MCP-CALC] ❌ 除数为零")
			return "", fmt.Errorf("除数不能为零")
		}
		result := fmt.Sprintf("%.2f", a/b)
		log.Printf("[MCP-CALC] ✅ 除法计算完成: %f / %f = %s", a, b, result)
		return result, nil
	}
	
	// 支持一些数学函数
	if strings.HasPrefix(expression, "sqrt(") && strings.HasSuffix(expression, ")") {
		log.Printf("[MCP-CALC] √ 检测到平方根运算")
		numStr := expression[5 : len(expression)-1]
		num, err := strconv.ParseFloat(numStr, 64)
		if err != nil {
			log.Printf("[MCP-CALC] ❌ 平方根数字解析失败: %v", err)
			return "", fmt.Errorf("无效的数字")
		}
		if num < 0 {
			log.Printf("[MCP-CALC] ❌ 负数平方根")
			return "", fmt.Errorf("不能计算负数的平方根")
		}
		result := fmt.Sprintf("%.2f", math.Sqrt(num))
		log.Printf("[MCP-CALC] ✅ 平方根计算完成: sqrt(%f) = %s", num, result)
		return result, nil
	}
	
	if strings.HasPrefix(expression, "pow(") && strings.HasSuffix(expression, ")") {
		log.Printf("[MCP-CALC] ^ 检测到幂运算")
		inner := expression[4 : len(expression)-1]
		parts := strings.Split(inner, ",")
		if len(parts) != 2 {
			log.Printf("[MCP-CALC] ❌ pow函数参数错误，参数数量: %d", len(parts))
			return "", fmt.Errorf("pow函数需要两个参数")
		}
		base, err1 := strconv.ParseFloat(strings.TrimSpace(parts[0]), 64)
		exp, err2 := strconv.ParseFloat(strings.TrimSpace(parts[1]), 64)
		if err1 != nil || err2 != nil {
			log.Printf("[MCP-CALC] ❌ 幂运算数字解析失败: %v, %v", err1, err2)
			return "", fmt.Errorf("无效的数字")
		}
		result := fmt.Sprintf("%.2f", math.Pow(base, exp))
		log.Printf("[MCP-CALC] ✅ 幂运算计算完成: pow(%f, %f) = %s", base, exp, result)
		return result, nil
	}
	
	log.Printf("[MCP-CALC] ❌ 不支持的表达式: %s", expression)
	return "", fmt.Errorf("不支持的表达式: %s", expression)
}

func main() {
	log.Printf("[MCP-SERVER] 🚀 启动MCP服务器...")
	
	timeService := &TimeService{}
	calcService := &CalculatorService{}

	server := mcp.NewServer("demo-mcp-server", "1.0.0")
	log.Printf("[MCP-SERVER] 📋 创建MCP服务器实例完成")

	// 注册获取时间的工具
	log.Printf("[MCP-SERVER] 🔧 注册时间查询工具...")
	server.AddTool(mcp.Tool{
		Name:        "get_time",
		Description: "获取指定地点的当前时间",
		InputSchema: map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"location": map[string]interface{}{
					"type":        "string",
					"description": "地点名称，如：北京、东京、纽约等",
				},
			},
			"required": []string{"location"},
		},
	}, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		log.Printf("[MCP-SERVER] 🕐 时间查询工具被调用，参数: %+v", args)
		location, ok := args["location"].(string)
		if !ok {
			log.Printf("[MCP-SERVER] ❌ 时间查询参数类型错误")
			return nil, fmt.Errorf("location参数必须是字符串")
		}
		result, err := timeService.GetTimeByLocation(location)
		if err != nil {
			log.Printf("[MCP-SERVER] ❌ 时间查询失败: %v", err)
		} else {
			log.Printf("[MCP-SERVER] ✅ 时间查询成功")
		}
		return result, err
	})

	// 注册计算工具
	log.Printf("[MCP-SERVER] 🔧 注册计算工具...")
	server.AddTool(mcp.Tool{
		Name:        "calculate",
		Description: "执行数学计算，支持基本四则运算和一些数学函数",
		InputSchema: map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"expression": map[string]interface{}{
					"type":        "string",
					"description": "数学表达式，如：1+2、10*5、sqrt(16)、pow(2,3)等",
				},
			},
			"required": []string{"expression"},
		},
	}, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		log.Printf("[MCP-SERVER] 🧮 计算工具被调用，参数: %+v", args)
		expression, ok := args["expression"].(string)
		if !ok {
			log.Printf("[MCP-SERVER] ❌ 计算参数类型错误")
			return nil, fmt.Errorf("expression参数必须是字符串")
		}
		result, err := calcService.Calculate(expression)
		if err != nil {
			log.Printf("[MCP-SERVER] ❌ 计算失败: %v", err)
		} else {
			log.Printf("[MCP-SERVER] ✅ 计算成功")
		}
		return result, err
	})

	log.Printf("[MCP-SERVER] ✅ 工具注册完成，开始运行服务器...")
	if err := server.Run(); err != nil {
		log.Fatal("[MCP-SERVER] ❌ MCP服务器启动失败:", err)
	}
}
